// // Copyright (c) 2009 All Right Reserved // // Stephen Toub // stoub@microsoft.com // 2009-01-01 // Contains ... namespace LargoCommon.Midi { using System; using System.Globalization; using System.IO; using System.Text; using Music; /// /// MIDI event to modify the tone with data from a pedal, lever, or other device; /// also used for miscellaneous controls such as volume and bank select. /// [Serializable] public sealed class VoiceController : VoiceEvent { #region Fields /// The category status byte for Controller messages. private const byte CategoryStatusByte = 0xB; /// The type of controller message (0x0 to 0x7F). private byte number; /// The value of the controller message (0x0 to 0x7F). private byte controlValue; #endregion #region Constructors /// Initializes a new instance of the VoiceController class. /// The delta-time since the previous message. /// The channel to which to write the message (0 through 15). /// The type of controller message to be written. /// The value of the controller message. public VoiceController(long deltaTime, MidiChannel channel, byte number, byte value) : base(deltaTime, CategoryStatusByte, channel) { this.Number = number; this.Value = value; } #endregion #region Properties /// Gets The first parameter as sent in the MIDI message. /// General musical property. public override byte Parameter1 => this.number; /// Gets The second parameter as sent in the MIDI message. /// General musical property. public override byte Parameter2 => this.controlValue; /// Gets or sets the value of the controller message (0x0 to 0x7F). /// General musical property. private byte Value { get => this.controlValue; set { if (value > 127) { value = (byte)(value % 128); //// throw new ArgumentOutOfRangeException("value", value, "The value must be in the range from 0 to 127."); } this.controlValue = value; } } /// Gets or sets type of controller message to be written (0x0 to 0x7F). /// General musical property. private byte Number { get => this.number; set => this.number = value; } #endregion #region To String /// Generate a string representation of the event. /// A string representation of the event. public override string ToString() { var sb = new StringBuilder(); sb.Append(base.ToString()); sb.Append("\t"); if (Enum.IsDefined(typeof(MidiController), (int)this.number)) { sb.Append((MidiController)this.number); } else { sb.Append("0x"); sb.Append(this.Number.ToString("X2", CultureInfo.CurrentCulture.NumberFormat)); } sb.Append("\t"); sb.Append("0x"); sb.Append(this.Value.ToString("X2", CultureInfo.CurrentCulture.NumberFormat)); return sb.ToString(); } #endregion #region Methods /// Write the event to the output stream. /// The stream to which the event should be written. public override void Write(Stream outputStream) { if (outputStream == null) { return; } //// Write out the base event information base.Write(outputStream); //// Write out the data outputStream.WriteByte(this.number); outputStream.WriteByte(this.controlValue); } #endregion } }